{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 基于物品的协同过滤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# coding: utf-8\n",
    "# -*- coding:utf-8 -*-\n",
    "import sys\n",
    "reload(sys)\n",
    "sys.setdefaultencoding(\"utf-8\")\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "import cPickle\n",
    "import scipy.io as sio\n",
    "import os\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读入数据做初始化\n",
    "    \n",
    "#用户和item的索引\n",
    "user_index = cPickle.load(open(\"user_index.pkl\", 'rb'))\n",
    "item_index = cPickle.load(open(\"item_index.pkl\", 'rb'))\n",
    "\n",
    "n_users = len(user_index)\n",
    "n_items = len(item_index)\n",
    "    \n",
    "#用户-物品关系矩阵R\n",
    "#user_item_scores = sio.mmread(\"user_items_scores\").todense()\n",
    "    \n",
    "#倒排表\n",
    "##每个用户播放的歌曲\n",
    "user_items = cPickle.load(open(\"user_items.pkl\", 'rb'))\n",
    "##事件参加的用户\n",
    "item_users = cPickle.load(open(\"item_users.pkl\", 'rb'))\n",
    "\n",
    "#所有item之间的相似度\n",
    "similarity_matrix = cPickle.load(open(\"items_similarity.pkl\", 'rb'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 根据相似度矩阵产生top推荐"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "cur_user = '5a905f000fc1ff3df7ca807d57edb608863db05d'\n",
    "\n",
    "cur_user_id = user_index[cur_user]\n",
    "cur_user_items = user_items[cur_user_id]\n",
    "\n",
    "n_cur_user_items = len(cur_user_items)\n",
    "user_sim_scores = np.zeros(n_cur_user_items)\n",
    "\n",
    "cur_similarity_matrix = np.matrix(np.zeros(shape=(n_cur_user_items, n_items)), float)\n",
    "\n",
    "cur_item_index = 0\n",
    "for i in cur_user_items:  # each item of user\n",
    "    cur_similarity_matrix[cur_item_index,:] = similarity_matrix[i,:]\n",
    "    cur_item_index = cur_item_index +1\n",
    "\n",
    "#Calculate a weighted average of the scores in similarity_matrix matrix for all user items.  \n",
    "user_sim_scores = cur_similarity_matrix.sum(axis=0)/float(cur_similarity_matrix.shape[0])\n",
    "user_sim_scores = np.array(user_sim_scores)[0].tolist()\n",
    "        \n",
    "#Sort the indices of user_sim_scores based upon their value\n",
    "#Also maintain the corresponding score\n",
    "sort_index = sorted(((e,i) for i,e in enumerate(list(user_sim_scores))), reverse=True)\n",
    "    \n",
    "#Create a dataframe from the following\n",
    "columns = ['user_id', 'item', 'score', 'rank']\n",
    "#index = np.arange(1) # array of numbers for the number of samples\n",
    "df = pd.DataFrame(columns=columns)\n",
    "         \n",
    "#Fill the dataframe with top 20 item based recommendations\n",
    "rank = 1 \n",
    "for i in range(0,len(sort_index)):\n",
    "    cur_item_index = sort_index[i][1] \n",
    "    cur_item = list (item_index.keys()) [list (item_index.values()).index (cur_item_index)]\n",
    "            \n",
    "    if ~np.isnan(sort_index[i][0]) and cur_item_index not in cur_user_items and rank <= 20:\n",
    "        df.loc[len(df)]=[cur_user,cur_item,sort_index[i][0],rank]\n",
    "        rank = rank+1       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item</th>\n",
       "      <th>score</th>\n",
       "      <th>rank</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOOFYTN12A6D4F9B35</td>\n",
       "      <td>0.083029</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOUSMXX12AB0185C24</td>\n",
       "      <td>0.077803</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOBONKR12A58A7A7E0</td>\n",
       "      <td>0.075808</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOTVLQY12A58A798C2</td>\n",
       "      <td>0.070376</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOPAYPV12AB017DB0C</td>\n",
       "      <td>0.068600</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOLGLUC12AB018A8FA</td>\n",
       "      <td>0.061915</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOGTDJQ12A8C13324F</td>\n",
       "      <td>0.056140</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOTWSXL12A8C143349</td>\n",
       "      <td>0.055730</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOMCMKG12A8C1347BF</td>\n",
       "      <td>0.049470</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOZVVRE12A8C143150</td>\n",
       "      <td>0.048731</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SONEWAX12AB018DD3F</td>\n",
       "      <td>0.044805</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOXVVSM12A8C142224</td>\n",
       "      <td>0.044543</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOOGNOZ12AAF3B2936</td>\n",
       "      <td>0.043671</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOSROFB12AAF3B4C5D</td>\n",
       "      <td>0.042828</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOBADEB12AB018275F</td>\n",
       "      <td>0.040932</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SODOWUC12AC9097E76</td>\n",
       "      <td>0.039390</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOISNSU12AC468C0D8</td>\n",
       "      <td>0.038662</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOOYDAZ12A58A7AE08</td>\n",
       "      <td>0.032961</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SOXQROF12AB0186B1D</td>\n",
       "      <td>0.032960</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>5a905f000fc1ff3df7ca807d57edb608863db05d</td>\n",
       "      <td>SONHWUN12AC468C014</td>\n",
       "      <td>0.031774</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     user_id                item     score  \\\n",
       "0   5a905f000fc1ff3df7ca807d57edb608863db05d  SOOFYTN12A6D4F9B35  0.083029   \n",
       "1   5a905f000fc1ff3df7ca807d57edb608863db05d  SOUSMXX12AB0185C24  0.077803   \n",
       "2   5a905f000fc1ff3df7ca807d57edb608863db05d  SOBONKR12A58A7A7E0  0.075808   \n",
       "3   5a905f000fc1ff3df7ca807d57edb608863db05d  SOTVLQY12A58A798C2  0.070376   \n",
       "4   5a905f000fc1ff3df7ca807d57edb608863db05d  SOPAYPV12AB017DB0C  0.068600   \n",
       "5   5a905f000fc1ff3df7ca807d57edb608863db05d  SOLGLUC12AB018A8FA  0.061915   \n",
       "6   5a905f000fc1ff3df7ca807d57edb608863db05d  SOGTDJQ12A8C13324F  0.056140   \n",
       "7   5a905f000fc1ff3df7ca807d57edb608863db05d  SOTWSXL12A8C143349  0.055730   \n",
       "8   5a905f000fc1ff3df7ca807d57edb608863db05d  SOMCMKG12A8C1347BF  0.049470   \n",
       "9   5a905f000fc1ff3df7ca807d57edb608863db05d  SOZVVRE12A8C143150  0.048731   \n",
       "10  5a905f000fc1ff3df7ca807d57edb608863db05d  SONEWAX12AB018DD3F  0.044805   \n",
       "11  5a905f000fc1ff3df7ca807d57edb608863db05d  SOXVVSM12A8C142224  0.044543   \n",
       "12  5a905f000fc1ff3df7ca807d57edb608863db05d  SOOGNOZ12AAF3B2936  0.043671   \n",
       "13  5a905f000fc1ff3df7ca807d57edb608863db05d  SOSROFB12AAF3B4C5D  0.042828   \n",
       "14  5a905f000fc1ff3df7ca807d57edb608863db05d  SOBADEB12AB018275F  0.040932   \n",
       "15  5a905f000fc1ff3df7ca807d57edb608863db05d  SODOWUC12AC9097E76  0.039390   \n",
       "16  5a905f000fc1ff3df7ca807d57edb608863db05d  SOISNSU12AC468C0D8  0.038662   \n",
       "17  5a905f000fc1ff3df7ca807d57edb608863db05d  SOOYDAZ12A58A7AE08  0.032961   \n",
       "18  5a905f000fc1ff3df7ca807d57edb608863db05d  SOXQROF12AB0186B1D  0.032960   \n",
       "19  5a905f000fc1ff3df7ca807d57edb608863db05d  SONHWUN12AC468C014  0.031774   \n",
       "\n",
       "   rank  \n",
       "0     1  \n",
       "1     2  \n",
       "2     3  \n",
       "3     4  \n",
       "4     5  \n",
       "5     6  \n",
       "6     7  \n",
       "7     8  \n",
       "8     9  \n",
       "9    10  \n",
       "10   11  \n",
       "11   12  \n",
       "12   13  \n",
       "13   14  \n",
       "14   15  \n",
       "15   16  \n",
       "16   17  \n",
       "17   18  \n",
       "18   19  \n",
       "19   20  "
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
